home *** CD-ROM | disk | FTP | other *** search
Text File | 1990-03-14 | 46.2 KB | 1,862 lines | [TEXT/MPS ] |
- ;; GCC machine description for Intel 80386.
- ;; Copyright (C) 1988 Free Software Foundation, Inc.
- ;; Mostly by William Schelter.
-
- ;; This file is part of GNU CC.
-
- ;; GNU CC is free software; you can redistribute it and/or modify
- ;; it under the terms of the GNU General Public License as published by
- ;; the Free Software Foundation; either version 1, or (at your option)
- ;; any later version.
-
- ;; GNU CC is distributed in the hope that it will be useful,
- ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
- ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ;; GNU General Public License for more details.
-
- ;; You should have received a copy of the GNU General Public License
- ;; along with GNU CC; see the file COPYING. If not, write to
- ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
-
- ;;- instruction definitions
-
- ;;- @@The original PO technology requires these to be ordered by speed,
- ;;- @@ so that assigner will pick the fastest.
-
- ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
-
- ;;- When naming insn's (operand 0 of define_insn) be careful about using
- ;;- names from other targets machine descriptions.
-
- ;;- cpp macro #define NOTICE_UPDATE_CC in file tm.h handles condition code
- ;;- updates for most instructions.
-
- ;;- Operand classes for the register allocator:
- ;;- 'a' for eax
- ;;- 'd' for edx
- ;;- 'c' for ecx
- ;;- 'b' for ebx
- ;;- 'f' for anything in FLOAT_REGS
- ;;- 'r' any (non-floating-point) register
- ;;- 'q' regs that allow byte operations (A, B, C and D)
- ;;- 'A' A and D registers
-
- ;; the special asm out single letter directives following a '%' are:
- ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of operands[1]
- ;; 's' output a '*'
- ;; 'w' If the operand is a REG, it uses the mode size to determine the
- ;; printing of the reg
-
-
- ;; Put tstsi first among test insns so it matches a CONST_INT operand.
-
- (define_insn "tstsi"
- [(set (cc0)
- (match_operand:SI 0 "general_operand" "rm"))]
- ""
- "*
- {
- operands[1] = const0_rtx;
- if (REG_P (operands[0]))
- return AS2 (test%L0,%0,%0);
- return AS2 (cmp%L0,%1,%0);
- }")
-
- (define_insn "tsthi"
- [(set (cc0)
- (match_operand:HI 0 "general_operand" "rm"))]
- ""
- "*
- {
- operands[1] = const0_rtx;
- if (REG_P (operands[0]))
- return AS2 (test%W0,%0,%0);
- return AS2 (cmp%W0,%1,%0);
- }")
-
- (define_insn "tstqi"
- [(set (cc0)
- (match_operand:QI 0 "general_operand" "qm"))]
- ""
- "*
- {
- operands[1] = const0_rtx;
- if (REG_P (operands[0]))
- return AS2 (test%B0,%0,%0);
- return AS2 (cmp%B0,%1,%0);
- }")
-
- (define_insn "tstsf"
- [(set (cc0)
- (match_operand:SF 0 "general_operand" "rm,f"))
- (clobber (reg:HI 0))]
- "TARGET_80387"
- "*
- {
- rtx xops[1];
- if (!FP_REG_P (operands[0]))
- fp_push_sf (operands[0]);
- /* fp_pop_level--; */
- xops[0] = FP_TOP;
- cc_status.flags |= CC_IN_80387;
- if (FP_REG_P (operands[0]) && ! top_dead_p (insn))
- output_asm_insn (\"ftst\;fnstsw %R0ax\;sahf\", xops);
- else
- output_asm_insn (\"ftst\;fstp %0(0)\;fnstsw %R0ax\;sahf\", xops);
- RETCOM (testsf);
- }")
-
- (define_insn "tstdf"
- [(set (cc0)
- (match_operand:DF 0 "general_operand" "rm,f"))
- (clobber (reg:HI 0))
- ]
- "TARGET_80387"
- "*
- {
- rtx xops[1];
- if (!FP_REG_P (operands[0]))
- fp_push_df (operands[0]);
- /* fp_pop_level--; */
- xops[0] = FP_TOP;
- cc_status.flags |= CC_IN_80387;
- if (FP_REG_P (operands[0]) && ! top_dead_p (insn))
- output_asm_insn (\"ftst\;fnstsw %R0ax\;sahf\", xops);
- else
- output_asm_insn (\"ftst\;fstp %0(0)\;fnstsw %R0ax\;sahf\", xops);
- RETCOM (testdf);
- }")
-
- ;;- compare instructions
-
- ;; Put cmpsi first among compare insns so it matches two CONST_INT operands.
-
- (define_insn "cmpsi"
- [(set (cc0)
- (compare (match_operand:SI 0 "general_operand" "mr,ri")
- (match_operand:SI 1 "general_operand" "ri,mr")))]
- ""
- "*
- {
- if (REG_P (operands[1])
- || (!REG_P (operands[0]) && GET_CODE (operands[0]) != MEM))
- {
- cc_status.flags |= CC_REVERSED;
- return AS2 (cmp%L0,%0,%1);
- }
- return AS2 (cmp%L0,%1,%0);
- }")
-
- (define_insn "cmphi"
- [(set (cc0)
- (compare (match_operand:HI 0 "general_operand" "mr,ri")
- (match_operand:HI 1 "general_operand" "ri,mr")))]
- ""
- "*
- {
- if (REG_P (operands[1])
- || (!REG_P (operands[0]) && GET_CODE (operands[0]) != MEM))
- {
- cc_status.flags |= CC_REVERSED;
- return AS2 (cmp%W0,%0,%1);
- }
- return AS2 (cmp%W0,%1,%0);
- }")
-
- (define_insn "cmpqi"
- [(set (cc0)
- (compare (match_operand:QI 0 "general_operand" "qn,mq")
- (match_operand:QI 1 "general_operand" "qm,nq")))]
- ""
- "*
- {
- if (REG_P (operands[1])
- || (!REG_P (operands[0]) && GET_CODE (operands[0]) != MEM))
- {
- cc_status.flags |= CC_REVERSED;
- return AS2 (cmp%B0,%0,%1);
- }
- return AS2 (cmp%B0,%1,%0);
- }")
-
- (define_insn "cmpdf"
- [(set (cc0)
- (compare (match_operand:DF 0 "general_operand" "m,f*r,m,f,r,!*r")
- (match_operand:DF 1 "general_operand" "m,m,f*r,r,f,*r")))
- (clobber (reg:SI 0))]
- "TARGET_80387"
- "*
- {
- if (FP_REG_P (operands[0]))
- {
- rtx tem = operands[1];
- operands[1] = operands[0];
- operands[0] = tem;
- cc_status.flags |= CC_REVERSED;
- }
- if (! FP_REG_P (operands[1]))
- output_movdf (FP_TOP, operands[1]);
- output_movdf (FP_TOP, operands[0]);
- /* fp_pop_level--;
- fp_pop_level--; */
- cc_status.flags |= CC_IN_80387;
- return \"fcompp\;fnstsw %R0ax\;sahf\";
- }")
-
- (define_insn "cmpsf"
- [(set (cc0)
- (compare (match_operand:SF 0 "general_operand" "m,f*r,m,f,r,!*r")
- (match_operand:SF 1 "general_operand" "m,m,f*r,r,f,*r")))
- (clobber (reg:SI 0))]
- "TARGET_80387"
- "*
- {
- if (FP_REG_P (operands[0]))
- {
- rtx tem = operands[1];
- operands[1] = operands[0];
- operands[0] = tem;
- cc_status.flags |= CC_REVERSED;
- }
- if (! FP_REG_P (operands[1]))
- output_movsf (FP_TOP, operands[1]);
- output_movsf (FP_TOP, operands[0]);
- /* fp_pop_level--;
- fp_pop_level--; */
- cc_status.flags |= CC_IN_80387;
- return \"fcompp\;fnstsw %R0ax\;sahf\";
- }")
-
- ;; logical compare
- (define_insn ""
- [(set (cc0)
- (and:SI (match_operand:SI 0 "general_operand" "rm,ri")
- (match_operand:SI 1 "general_operand" "ri,rm")))]
- ""
- "*
- {
- if (GET_CODE (operands[1]) == CONST_INT || GET_CODE (operands[0]) == MEM)
- return AS2 (test%L0,%1,%0);
- return AS2 (test%L0,%0,%1);
- }")
-
- (define_insn ""
- [(set (cc0)
- (and:HI (match_operand:HI 0 "general_operand" "rm,ri")
- (match_operand:HI 1 "general_operand" "ri,rm")))]
- ""
- "*
- {
- if (GET_CODE (operands[1]) == CONST_INT || GET_CODE (operands[0]) == MEM)
- return AS2 (test%W0,%1,%0);
- return AS2 (test%W0,%0,%1);
- }")
-
- (define_insn ""
- [(set (cc0)
- (and:QI (match_operand:QI 0 "general_operand" "qm,qi")
- (match_operand:QI 1 "general_operand" "qi,qm")))]
- ""
- "*
- {
- if (GET_CODE (operands[1]) == CONST_INT || GET_CODE (operands[0]) == MEM)
- return AS2 (test%B0,%1,%0);
- return AS2 (test%B0,%0,%1);
- }")
-
- ;; move instructions.
- ;; There is one for each machine mode,
- ;; and each is preceded by a corresponding push-insn pattern
- ;; (since pushes are not general_operands on the 386).
-
- (define_insn ""
- [(set (match_operand:SI 0 "push_operand" "=<")
- (match_operand:SI 1 "general_operand" "g"))]
- ""
- "push%L0 %1")
-
- ;; General case of fullword move.
- (define_insn "movsi"
- [(set (match_operand:SI 0 "general_operand" "=g,r")
- (match_operand:SI 1 "general_operand" "ri,m"))]
- ""
- "*
- {
- rtx link;
- if (operands[1] == const0_rtx && REG_P (operands[0]))
- return \"xor%L0 %0,%0\";
- if (operands[1] == const1_rtx
- && (link = find_reg_note (insn, REG_WAS_0, 0))
- /* Make sure the insn that stored the 0 is still present. */
- && ! XEXP (link, 0)->volatil
- && GET_CODE (XEXP (link, 0)) != NOTE
- /* Make sure cross jumping didn't happen here. */
- && no_labels_between_p (XEXP (link, 0), insn))
- /* Fastest way to change a 0 to a 1. */
- return \"inc%L0 %0\";
- return \"mov%L0 %1,%0\";
- }")
-
- (define_insn ""
- [(set (match_operand:HI 0 "push_operand" "=<")
- (match_operand:HI 1 "general_operand" "g"))]
- ""
- "push%W0 %1")
-
- (define_insn "movhi"
- [(set (match_operand:HI 0 "general_operand" "=g,r")
- (match_operand:HI 1 "general_operand" "ri,m"))]
- ""
- "*
- {
- rtx link;
- if (operands[1] == const0_rtx && REG_P (operands[0]))
- return \"xor%W0 %0,%0\";
- if (operands[1] == const1_rtx
- && (link = find_reg_note (insn, REG_WAS_0, 0))
- /* Make sure the insn that stored the 0 is still present. */
- && ! XEXP (link, 0)->volatil
- && GET_CODE (XEXP (link, 0)) != NOTE
- /* Make sure cross jumping didn't happen here. */
- && no_labels_between_p (XEXP (link, 0), insn))
- /* Fastest way to change a 0 to a 1. */
- return \"inc%W0 %0\";
- return \"mov%W0 %1,%0\";
- }")
-
- ;; emit_push_insn when it calls move_by_pieces
- ;; requires an insn to "push a byte".
- ;; But actually we use pushw, which has the effect of rounding
- ;; the amount pushed up to a halfword.
- (define_insn ""
- [(set (match_operand:QI 0 "push_operand" "=<")
- (match_operand:QI 1 "general_operand" "q"))]
- ""
- "*
- {
- operands[1] = gen_rtx (REG, HImode, REGNO (operands[1]));
- return \"push%W0 %1\";
- }")
-
- (define_insn "movqi"
- [(set (match_operand:QI 0 "general_operand" "=q,*r,m")
- (match_operand:QI 1 "general_operand" "*g,q,qi"))]
- ""
- "*
- {
- rtx link;
- if (operands[1] == const0_rtx && REG_P (operands[0]))
- return \"xor%B0 %0,%0\";
- if (operands[1] == const1_rtx
- && (link = find_reg_note (insn, REG_WAS_0, 0))
- /* Make sure the insn that stored the 0 is still present. */
- && ! XEXP (link, 0)->volatil
- && GET_CODE (XEXP (link, 0)) != NOTE
- /* Make sure cross jumping didn't happen here. */
- && no_labels_between_p (XEXP (link, 0), insn))
- /* Fastest way to change a 0 to a 1. */
- return \"inc%B0 %0\";
- /* If mov%B0 isn't allowed for one of these regs, use mov%W0. */
- if (NON_QI_REG_P (operands[0]) || NON_QI_REG_P (operands[1]))
- return (AS2 (mov%W0,%w1,%w0));
- return (AS2 (mov%B0,%1,%0));
- }")
-
- ; I suspect nothing can ever match this ???
- ;(define_insn ""
- ; [(set (match_operand:SF 0 "general_operand" "rm")
- ; (match_operand:SF 1 "general_operand" "f"))
- ; (clobber (reg:SF 8))]
- ; ""
- ; "*
- ;{
- ; output_asm_insn ("???", operands);
- ; fpop_sf (operands[0]);
- ; RETCOM (movsf_clobber);
- ;}")
-
- (define_insn ""
- [(set (match_operand:SF 0 "push_operand" "=<,<")
- (match_operand:SF 1 "general_operand" "gF,f"))]
- ""
- "*
- {
- if (FP_REG_P (operands[1]))
- {
- rtx xops[3];
- xops[0] = AT_SP (SFmode);
- xops[1] = gen_rtx (CONST_INT, VOIDmode, 4);
- xops[2] = stack_pointer_rtx;
- /* fp_pop_level--; */
- output_asm_insn (AS2 (sub%L0,%1,%2), xops);
- if (top_dead_p (insn))
- output_asm_insn (\"fstp%S0 %0\", xops);
- else
- output_asm_insn (\"fst%S0\", xops);
- RET;
- }
- return \"push%L0 %1\";
- }")
-
- (define_insn "movsf"
- [(set (match_operand:SF 0 "general_operand" "=rf,rmf,!rm")
- (match_operand:SF 1 "general_operand" "m,rf,F"))]
- ""
- "*
- {
- if (FP_REG_P (operands[1])
- && !FP_REG_P (operands[0])
- && !top_dead_p (insn))
- fp_store_sf (operands[0]);
- else
- output_movsf (operands[0], operands[1]);
- RETCOM (movsf);
- }")
-
- ;;should change to handle the memory operands[1] without doing df push..
- (define_insn ""
- [(set (match_operand:DF 0 "push_operand" "=<,<")
- (match_operand:DF 1 "general_operand" "gF,f"))]
- ""
- "*
- {
- if (FP_REG_P (operands[1]))
- {
- rtx xops[3];
- xops[0] = AT_SP (DFmode);
- xops[1] = gen_rtx (CONST_INT, VOIDmode, 8);
- xops[2] = stack_pointer_rtx;
- /* fp_pop_level--; */
- output_asm_insn (AS2 (sub%L0,%1,%2), xops);
- if (top_dead_p(insn))
- output_asm_insn (\"fstp%Q0 %0\", xops);
- else
- output_asm_insn (\"fst%Q0 %0\", xops);
- RETCOM (pushdf);
- }
- else
- return output_move_double (operands);
- }")
-
- (define_insn "movdf"
- [(set (match_operand:DF 0 "general_operand" "=&rf,rmf,!rm")
- (match_operand:DF 1 "general_operand" "m,fr,F"))]
- ""
- "*
- {
- if (FP_REG_P (operands[1])
- && ! FP_REG_P (operands[0])
- && ! top_dead_p (insn))
- fp_store_df (operands[0]);
- else
- output_movdf (operands[0], operands[1]);
- RETCOM (movdf);
- }")
-
- (define_insn ""
- [(set (match_operand:DI 0 "push_operand" "=<")
- (match_operand:DI 1 "general_operand" "roiF"))]
- ""
- "*
- {
- return output_move_double (operands);
- }")
-
- (define_insn "movdi"
- [(set (match_operand:DI 0 "general_operand" "=&r,rm")
- (match_operand:DI 1 "general_operand" "m,riF"))]
- ""
- "*
- {
- return output_move_double (operands);
- }")
-
- ;; These go after the move instructions
- ;; because the move instructions are better (require no spilling)
- ;; when they can apply. But these go before the add and subtract insns
- ;; because it is often shorter to use these when both apply.
-
- ;Lennart Augustsson <augustss@cs.chalmers.se>
- ;says this pattern just makes slower code:
- ; pushl %ebp
- ; addl $-80,(%esp)
- ;instead of
- ; leal -80(%ebp),%eax
- ; pushl %eax
- ;
- ;(define_insn ""
- ; [(set (match_operand:SI 0 "push_operand" "=<")
- ; (plus:SI (match_operand:SI 1 "general_operand" "%r")
- ; (match_operand:SI 2 "general_operand" "ri")))]
- ; ""
- ; "*
- ;{
- ; rtx xops[4];
- ; xops[0] = operands[0];
- ; xops[1] = operands[1];
- ; xops[2] = operands[2];
- ; xops[3] = gen_rtx (MEM, SImode, stack_pointer_rtx);
- ; output_asm_insn (\"push%z1 %1\", xops);
- ; output_asm_insn (AS2 (add%z3,%2,%3), xops);
- ; RET;
- ;}")
-
- (define_insn ""
- [(set (match_operand:SI 0 "general_operand" "=g")
- (plus:SI (match_operand:SI 1 "general_operand" "0")
- (const_int 1)))]
- ""
- "inc%L0 %0")
-
- (define_insn ""
- [(set (match_operand:SI 0 "general_operand" "=g")
- (plus:SI (match_operand:SI 1 "general_operand" "0")
- (const_int -1)))]
- ""
- "dec%L0 %0")
-
- (define_insn ""
- [(set (match_operand:SI 0 "general_operand" "=g")
- (minus:SI (match_operand:SI 1 "general_operand" "0")
- (const_int 1)))]
- ""
- "dec%L0 %0")
-
- (define_insn ""
- [(set (match_operand:SI 0 "register_operand" "=r")
- (match_operand:QI 1 "address_operand" "p"))]
- ""
- "*
- {
- CC_STATUS_INIT;
- /* Adding a constant to a register is faster with an add. */
- if (GET_CODE (operands[1]) == PLUS
- && GET_CODE (XEXP (operands[1], 1)) == CONST_INT
- && rtx_equal_p (operands[0], XEXP (operands[1], 0)))
- {
- operands[1] = XEXP (operands[1], 1);
- return AS2 (add%L0,%1,%0);
- }
- return \"lea%L0 %a1,%0\";
- }")
-
- ;;- conversion instructions
- ;;- NONE
-
- ;;- truncation instructions
- (define_insn "truncsiqi2"
- [(set (match_operand:QI 0 "general_operand" "=qm,q")
- (truncate:QI
- (match_operand:SI 1 "general_operand" "qi,m")))]
- ""
- "mov%B0 %b1,%0")
-
- (define_insn "trunchiqi2"
- [(set (match_operand:QI 0 "general_operand" "=qm,q")
- (truncate:QI
- (match_operand:HI 1 "general_operand" "qi,m")))]
- ""
- "mov%B0 %b1,%0")
-
- (define_insn "truncsihi2"
- [(set (match_operand:HI 0 "general_operand" "=rm,r")
- (truncate:HI
- (match_operand:SI 1 "general_operand" "ri,m")))]
- ""
- "mov%W0 %w1,%0")
-
- ;;- zero extension instructions
- ;; Note that the one starting from HImode comes before those for QImode
- ;; so that a constant operand will match HImode, not QImode.
-
- (define_insn "zero_extendhisi2"
- [(set (match_operand:SI 0 "general_operand" "=r")
- (zero_extend:SI
- (match_operand:HI 1 "general_operand" "rm")))]
- ""
- "movz%W0%L0 %1,%0")
-
- (define_insn "zero_extendqihi2"
- [(set (match_operand:HI 0 "general_operand" "=r")
- (zero_extend:HI
- (match_operand:QI 1 "general_operand" "qm")))]
- ""
- "movz%B0%W0 %1,%0")
-
- (define_insn "zero_extendqisi2"
- [(set (match_operand:SI 0 "general_operand" "=r")
- (zero_extend:SI
- (match_operand:QI 1 "general_operand" "qm")))]
- ""
- "movz%B0%L0 %1,%0")
-
- ;;- sign extension instructions
- ;; Note that the one starting from HImode comes before those for QImode
- ;; so that a constant operand will match HImode, not QImode.
-
- /*
- (define_insn "extendsidi2"
- [(set (match_operand:DI 0 "general_operand" "=a")
- (sign_extend:DI
- (match_operand:SI 1 "general_operand" "a")))]
- ""
- "clq")
- */
-
- (define_insn "extendhisi2"
- [(set (match_operand:SI 0 "general_operand" "=r")
- (sign_extend:SI
- (match_operand:HI 1 "general_operand" "rm")))]
- ""
- "movs%W0%L0 %1,%0")
-
- (define_insn "extendqihi2"
- [(set (match_operand:HI 0 "general_operand" "=r")
- (sign_extend:HI
- (match_operand:QI 1 "general_operand" "qm")))]
- ""
- "movs%B0%W0 %1,%0")
-
- (define_insn "extendqisi2"
- [(set (match_operand:SI 0 "general_operand" "=r")
- (sign_extend:SI
- (match_operand:QI 1 "general_operand" "qm")))]
- ""
- "movs%B0%L0 %1,%0"
- )
-
- ;; Conversions between float and double.
-
- (define_insn "extendsfdf2"
- [(set (match_operand:DF 0 "general_operand" "=fm,f,fm,fm")
- (float_extend:DF
- (match_operand:SF 1 "general_operand" "m,0,f,!*r")))]
- "TARGET_80387"
- "*
- {
- if (FP_REG_P (operands[0]))
- {
- output_movsf (operands[0], operands[1]);
- RET;
- }
- if (FP_REG_P (operands[1]))
- {
- if (top_dead_p (insn))
- fp_pop_df (operands[0]);
- else
- fp_store_df (operands[0]);
- RET;
- }
- output_movsf (FP_TOP, operands[1]);
- fp_pop_df (operands[0]);
- RETCOM (extendsfdf2);
- }")
-
- ;; This cannot output into an f-reg because there is no way to be
- ;; sure of truncating in that case.
- (define_insn "truncdfsf2"
- [(set (match_operand:SF 0 "general_operand" "=m,!*r")
- (float_truncate:SF
- (match_operand:DF 1 "general_operand" "f,f")))]
- "TARGET_80387"
- "*
- {
- if (top_dead_p (insn))
- fp_pop_sf (operands[0]);
- else
- fp_store_sf (operands[0]);
- RETCOM (truncdfsf2);
- }")
-
- ;; Conversion between fixed point and floating point.
- ;; Note that among the fix-to-float insns
- ;; the ones that start with SImode come first.
- ;; That is so that an operand that is a CONST_INT
- ;; (and therefore lacks a specific machine mode).
- ;; will be recognized as SImode (which is always valid)
- ;; rather than as QImode or HImode. The 80387 would not know
- ;; what to do with the smaller sizes anyway. (I think).
-
- (define_insn "floatsisf2"
- [(set (match_operand:SF 0 "general_operand" "=fm,fm")
- (float:SF (match_operand:SI 1 "general_operand" "m,!*r")))]
- "TARGET_80387"
- "*
- {
- /* fp_pop_level++; */
-
- if (GET_CODE (operands[1]) != MEM)
- {
- rtx xops[2];
- output_asm_insn (\"push%L0 %1\", operands);
- operands[1] = AT_SP (SImode);
- output_asm_insn (\"fild%L0 %1\", operands);
- xops[0] = stack_pointer_rtx;
- xops[1] = gen_rtx (CONST_INT, VOIDmode, 4);
- output_asm_insn (AS2 (add%L0,%1,%0), xops);
- }
- else
- output_asm_insn (\"fild%L0 %1\", operands);
-
- if (! FP_REG_P (operands[0]))
- {
- /* fp_pop_level--; */
- return \"fstp%S0 %0\";
- }
- RET;
- }")
-
- (define_insn "floatsidf2"
- [(set (match_operand:DF 0 "general_operand" "=fm,fm")
- (float:DF (match_operand:SI 1 "general_operand" "m,!*r")))]
- "TARGET_80387"
- "*
- {
- /* fp_pop_level++; */
- if (GET_CODE (operands[1]) != MEM)
- {
- rtx xops[2];
- output_asm_insn (\"push%L0 %1\", operands);
- operands[1] = AT_SP (SImode);
- output_asm_insn (\"fild%L0 %1\", operands);
- xops[0] = stack_pointer_rtx;
- xops[1] = gen_rtx (CONST_INT, VOIDmode, 4);
- output_asm_insn (AS2 (add%L0,%1,%0), xops);
- }
- else
- output_asm_insn (\"fild%L0 %1\", operands);
- if (! FP_REG_P (operands[0]))
- {
- /* fp_pop_level--; */
- return \"fstp%Q0 %0\";
- }
- RET;
- }")
-
- ;; Convert a float to a float whose value is an integer.
- ;; This is the first stage of converting it to an integer type.
-
- ;; On the 387 truncating doub to an short integer shor can be performed:
-
- ; fstcw -4(%esp) ;save cw
- ; movw -4(%esp),%ax
- ; orw $0x0c00,%ax ;set rounding to chop towards zero
- ; movw %ax,-2(%esp) ;
- ; fldcw -2(%esp) ;
- ; fldl doubl
- ; fistpl -12(%esp) ;store the round value
- ; fldcw -4(%esp) ;restore cw
- ; movl -12(%esp),%eax
- ; movw %ax,shor ; move the result into shor.
-
- ;; but it is probably better to have a call, rather than waste this
- ;; space. The last instruction would have been a movl if were
- ;; going to an int instead of a short.
- ;; For the moment we will go with the soft float for these.
-
- /* These are incorrect since they don't set the rounding bits of CW flag.
- The proper way to do that is to make the function prologue save the CW
- and also construct the alternate CW value needed for these insns.
- Then these insns can output two fldcw's, referring to fixed places in
- the stack frame.
-
- ;; Convert a float whose value is an integer
- ;; to an actual integer. Second stage of converting float to integer type.
-
- (define_insn "fix_truncsfqi2"
- [(set (match_operand:QI 0 "general_operand" "=m,?*q")
- (fix:QI (fix:SF (match_operand:SF 1 "general_operand" "f,f"))))]
- "TARGET_80387"
- "*
- {
- fp_pop_int (operands[0]);
- RET;
- }")
-
- (define_insn "fix_truncsfhi2"
- [(set (match_operand:HI 0 "general_operand" "=m,?*r")
- (fix:HI (fix:SF (match_operand:SF 1 "general_operand" "f,f"))))]
- "TARGET_80387"
- "*
- {
- fp_pop_int (operands[0]);
- RET;
- }")
-
- (define_insn "fix_truncsfsi2"
- [(set (match_operand:SI 0 "general_operand" "=m,?*r")
- (fix:SI (fix:SF (match_operand:SF 1 "general_operand" "f,f"))))]
- "TARGET_80387"
- "*
- {
- fp_pop_int (operands[0]);
- RET;
- }")
-
- (define_insn "fix_truncdfqi2"
- [(set (match_operand:QI 0 "general_operand" "=m,?*q")
- (fix:QI (fix:DF (match_operand:DF 1 "general_operand" "f,f"))))]
-
- "TARGET_80387"
- "*
- {
- fp_pop_int (operands[0]);
- RET;
- }")
-
-
- (define_insn "fix_truncdfhi2"
- [(set (match_operand:HI 0 "general_operand" "=m,?*r")
- (fix:HI (fix:DF (match_operand:DF 1 "general_operand" "f,f"))))]
- "TARGET_80387"
- "*
- {
- fp_pop_int (operands[0]);
- RET;
- }")
-
-
- (define_insn "fix_truncdfsi2"
- [(set (match_operand:SI 0 "general_operand" "=m,?*r")
- (fix:SI (fix:DF (match_operand:DF 1 "general_operand" "f,f"))))]
- "TARGET_80387"
- "*
- {
- fp_pop_int (operands[0]);
- RET;
- }")
- */
-
-
- ;;- add instructions
- ;;moved incl to above leal
-
- (define_insn "addsi3"
- [(set (match_operand:SI 0 "general_operand" "=rm,r")
- (plus:SI (match_operand:SI 1 "general_operand" "%0,0")
- (match_operand:SI 2 "general_operand" "ri,rm")))]
- ""
- "add%L0 %2,%0")
-
- (define_insn ""
- [(set (match_operand:HI 0 "general_operand" "=g")
- (plus:HI (match_operand:HI 1 "general_operand" "0")
- (const_int 1)))]
- ""
- "inc%W0 %0")
-
- (define_insn "addhi3"
- [(set (match_operand:HI 0 "general_operand" "=rm,r")
- (plus:HI (match_operand:HI 1 "general_operand" "%0,0")
- (match_operand:HI 2 "general_operand" "ri,rm")))]
- ""
- "add%W0 %2,%0")
-
- (define_insn ""
- [(set (match_operand:QI 0 "general_operand" "=qm")
- (plus:QI (match_operand:QI 1 "general_operand" "0")
- (const_int 1)))]
- ""
- "inc%B0 %0")
-
- (define_insn "addqi3"
- [(set (match_operand:QI 0 "general_operand" "=m,q")
- (plus:QI (match_operand:QI 1 "general_operand" "%0,0")
- (match_operand:QI 2 "general_operand" "qn,qmn")))]
- ""
- "add%B0 %2,%0")
-
- ;;had "fmF,m"
-
- (define_insn "adddf3"
- [(set (match_operand:DF 0 "general_operand" "=f,m,f")
- (plus:DF (match_operand:DF 1 "general_operand" "%0,0,0")
- (match_operand:DF 2 "general_operand" "m,!f,!*r")))]
- "TARGET_80387"
- "*FP_CALL (\"fadd%z0 %0\", \"fadd%z0 %0\", 2)")
-
- (define_insn "addsf3"
- [(set (match_operand:SF 0 "general_operand" "=f,m,f")
- (plus:SF (match_operand:SF 1 "general_operand" "%0,0,0")
- (match_operand:SF 2 "general_operand" "m,!f,!*r")))]
- "TARGET_80387"
- "*FP_CALL (\"fadd%z0 %0\", \"fadd%z0 %0\", 2)")
-
- ;;- subtract instructions
-
- ;;moved decl above leal
-
- (define_insn "subsi3"
- [(set (match_operand:SI 0 "general_operand" "=rm,r")
- (minus:SI (match_operand:SI 1 "general_operand" "0,0")
- (match_operand:SI 2 "general_operand" "ri,rm")))]
- ""
- "sub%L0 %2,%0")
-
- (define_insn ""
- [(set (match_operand:HI 0 "general_operand" "=g")
- (minus:HI (match_operand:HI 1 "general_operand" "0")
- (const_int 1)))]
- ""
- "dec%W0 %0")
-
- (define_insn "subhi3"
- [(set (match_operand:HI 0 "general_operand" "=rm,r")
- (minus:HI (match_operand:HI 1 "general_operand" "0,0")
- (match_operand:HI 2 "general_operand" "ri,rm")))]
- ""
- "sub%W0 %2,%0")
-
- (define_insn ""
- [(set (match_operand:QI 0 "general_operand" "=qm")
- (minus:QI (match_operand:QI 1 "general_operand" "0")
- (const_int 1)))]
- ""
- "dec%B0 %0")
-
- (define_insn "subqi3"
- [(set (match_operand:QI 0 "general_operand" "=m,q")
- (minus:QI (match_operand:QI 1 "general_operand" "0,0")
- (match_operand:QI 2 "general_operand" "qn,qmn")))]
- ""
- "sub%B0 %2,%0")
-
- (define_insn "subdf3"
- [(set (match_operand:DF 0 "general_operand" "=f,m,f,f")
- (minus:DF (match_operand:DF 1 "general_operand" "0,0,0,m")
- (match_operand:DF 2 "general_operand" "m,!f,!*r,*0")))]
- "TARGET_80387"
- "*FP_CALL (\"fsub%z0 %0\", \"fsubr%z0 %0\", 2)")
-
-
- (define_insn "subsf3"
- [(set (match_operand:SF 0 "general_operand" "=f,m,f,f")
- (minus:SF (match_operand:SF 1 "general_operand" "0,0,0,m")
- (match_operand:SF 2 "general_operand" "m,!f,!*r,*0")))]
- "TARGET_80387"
- "*FP_CALL (\"fsub%z0 %0\", \"fsubr%z0 %0\", 2)")
-
- ;;- multiply instructions
-
- ;(define_insn "mulqi3"
- ; [(set (match_operand:QI 0 "general_operand" "=a")
- ; (mult:QI (match_operand:QI 1 "general_operand" "%0")
- ; (match_operand:QI 2 "general_operand" "qm")))]
- ; ""
- ; "mul%B0 %2,%0")
-
- (define_insn "mulhi3"
- [(set (match_operand:HI 0 "general_operand" "=r,r")
- (mult:SI (match_operand:HI 1 "general_operand" "%0,rm")
- (match_operand:HI 2 "general_operand" "g,i")))]
- ""
- "*
- {
- if (GET_CODE (operands[1]) == REG
- && REGNO (operands[1]) == REGNO (operands[0])
- && (GET_CODE (operands[2]) == MEM
- || GET_CODE (operands[2]) == REG))
- /* Assembler has weird restrictions. */
- return AS2 (imul%W0,%2,%0);
- return AS3 (imul%W0,%2,%1,%0);
- }")
-
- (define_insn "mulsi3"
- [(set (match_operand:SI 0 "general_operand" "=r,r")
- (mult:SI (match_operand:SI 1 "general_operand" "%0,rm")
- (match_operand:SI 2 "general_operand" "g,i")))]
- ""
- "*
- {
- if (GET_CODE (operands[1]) == REG
- && REGNO (operands[1]) == REGNO (operands[0])
- && (GET_CODE (operands[2]) == MEM
- || GET_CODE (operands[2]) == REG))
- /* Assembler has weird restrictions. */
- return AS2 (imul%L0,%2,%0);
- return AS3 (imul%L0,%2,%1,%0);
- }")
-
- ;; Turned off due to possible assembler bug.
- ;(define_insn "umulqi3"
- ; [(set (match_operand:QI 0 "general_operand" "=a")
- ; (umult:QI (match_operand:QI 1 "general_operand" "%0")
- ; (match_operand:QI 2 "general_operand" "qm")))]
- ; ""
- ; "mul%B0 %2,%0")
-
- ;(define_insn "umulqihi3"
- ; [(set (match_operand:HI 0 "general_operand" "=a")
- ; (umult:HI (match_operand:QI 1 "general_operand" "%0")
- ; (match_operand:QI 2 "general_operand" "qm")))]
- ; ""
- ; "mul%B0 %2,%0")
-
- (define_insn "umulhi3"
- [(set (match_operand:HI 0 "general_operand" "=a")
- (umult:SI (match_operand:HI 1 "general_operand" "%0")
- (match_operand:HI 2 "general_operand" "rm")))
- (clobber (reg:HI 1))]
- ""
- "mul%W0 %2,%0")
-
- (define_insn "umulsi3"
- [(set (match_operand:SI 0 "general_operand" "=a")
- (umult:SI (match_operand:SI 1 "general_operand" "%0")
- (match_operand:SI 2 "general_operand" "rm")))
- (clobber (reg:SI 1))]
- ""
- "mul%L0 %2,%0")
-
- (define_insn "muldf3"
- [(set (match_operand:DF 0 "general_operand" "=f,m,f")
- (mult:DF (match_operand:DF 1 "general_operand" "%0,0,0")
- (match_operand:DF 2 "general_operand" "m,!f,!*r")))]
- "TARGET_80387"
- "*FP_CALL (\"fmul%z0 %0\", \"fmul%z0 %0\", 2)
- ")
-
- (define_insn "mulsf3"
- [(set (match_operand:SF 0 "general_operand" "=f,m,f")
- (mult:SF (match_operand:SF 1 "general_operand" "%0,0,0")
- (match_operand:SF 2 "general_operand" "m,!f,!*r")))]
- "TARGET_80387"
- "*FP_CALL (\"fmul%z0 %0\", \"fmul%z0 %0\", 2)
- ")
-
- ;;- divide instructions
- (define_insn "divdf3"
- [(set (match_operand:DF 0 "general_operand" "=f,m,f,f")
- (div:DF (match_operand:DF 1 "general_operand" "0,0,0,m")
- (match_operand:DF 2 "general_operand" "m,!f,!*r,*0")))]
- "TARGET_80387"
- "*FP_CALL (\"fdiv%z0 %0\", \"fdivr%z0 %0\", 2)
- ")
-
- (define_insn "divsf3"
- [(set (match_operand:SF 0 "general_operand" "=f,m,f,f")
- (div:SF (match_operand:SF 1 "general_operand" "0,0,0,m")
- (match_operand:SF 2 "general_operand" "m,!f,!*r,*0")))]
- "TARGET_80387"
- "*FP_CALL (\"fdiv%z0 %0\", \"fdivr%z0 %0\", 2)
- ")
-
- ;; Remainder instructions.
-
- (define_insn "divmodsi4"
- [(set (match_operand:SI 0 "general_operand" "=a")
- (div:SI (match_operand:SI 1 "general_operand" "0")
- (match_operand:SI 2 "general_operand" "rm")))
- (set (match_operand:SI 3 "general_operand" "=&d")
- (mod:SI (match_dup 1) (match_dup 2)))]
- ""
- "cltd\;idiv%L0 %2")
-
- (define_insn "udivmodsi4"
- [(set (match_operand:SI 0 "general_operand" "=a")
- (udiv:SI (match_operand:SI 1 "general_operand" "0")
- (match_operand:SI 2 "general_operand" "rm")))
- (set (match_operand:SI 3 "general_operand" "=&d")
- (umod:SI (match_dup 1) (match_dup 2)))]
- ""
- "xor%L0 %3,%3\;div%L0 %2")
-
- /*
- ;;this should be a valid double division which we may want to add
-
- (define_insn ""
- [(set (match_operand:SI 0 "general_operand" "=a")
- (udiv:DI (match_operand:DI 1 "general_operand" "a")
- (match_operand:SI 2 "general_operand" "rm")))
- (set (match_operand:SI 3 "general_operand" "=d")
- (umod:SI (match_dup 1) (match_dup 2)))]
- ""
- "div%L0 %2,%0")
- */
-
- ;;- and instructions
-
- ;; The `r' in `rm' for operand 3 looks redundant, but it causes
- ;; optional reloads to be generated if op 3 is a pseudo in a stack slot.
-
- (define_insn "andsi3"
- [(set (match_operand:SI 0 "general_operand" "=rm,r")
- (and:SI (match_operand:SI 1 "general_operand" "%0,0")
- (match_operand:SI 2 "general_operand" "ri,rm")))]
- ""
- "and%L0 %2,%0")
-
- (define_insn "andhi3"
- [(set (match_operand:HI 0 "general_operand" "=rm,r")
- (and:HI (match_operand:HI 1 "general_operand" "%0,0")
- (match_operand:HI 2 "general_operand" "ri,rm")))]
- ""
- "and%W0 %2,%0")
-
- (define_insn "andqi3"
- [(set (match_operand:QI 0 "general_operand" "=m,q")
- (and:QI (match_operand:QI 1 "general_operand" "%0,0")
- (match_operand:QI 2 "general_operand" "qn,qmn")))]
- ""
- "and%B0 %2,%0")
-
- /* I am nervous about these two.. add them later..
- ;I presume this means that we have something in say op0= eax which is small
- ;and we want to and it with memory so we can do this by just an
- ;andb m,%al and have success.
- (define_insn ""
- [(set (match_operand:SI 0 "general_operand" "=r")
- (and:SI (zero_extend:SI (match_operand:HI 1 "general_operand" "rm"))
- (match_operand:SI 2 "general_operand" "0")))]
- "GET_CODE (operands[2]) == CONST_INT
- && (unsigned int) INTVAL (operands[2]) < (1 << GET_MODE_BITSIZE (HImode))"
- "and%W0 %1,%0")
-
- (define_insn ""
- [(set (match_operand:SI 0 "general_operand" "=q")
- (and:SI (zero_extend:SI (match_operand:QI 1 "general_operand" "qm"))
- (match_operand:SI 2 "general_operand" "0")))]
- "GET_CODE (operands[2]) == CONST_INT
- && (unsigned int) INTVAL (operands[2]) < (1 << GET_MODE_BITSIZE (QImode))"
- "and%L0 %1,%0")
-
- */
-
-
-
- ;;- Bit set (inclusive or) instructions
-
- (define_insn "iorsi3"
- [(set (match_operand:SI 0 "general_operand" "=rm,r")
- (ior:SI (match_operand:SI 1 "general_operand" "%0,0")
- (match_operand:SI 2 "general_operand" "ri,rm")))]
- ""
- "or%L0 %2,%0")
-
- (define_insn "iorhi3"
- [(set (match_operand:HI 0 "general_operand" "=rm,r")
- (ior:HI (match_operand:HI 1 "general_operand" "%0,0")
- (match_operand:HI 2 "general_operand" "ri,rm")))]
- ""
- "or%W0 %2,%0")
-
- (define_insn "iorqi3"
- [(set (match_operand:QI 0 "general_operand" "=m,q")
- (ior:QI (match_operand:QI 1 "general_operand" "%0,0")
- (match_operand:QI 2 "general_operand" "qn,qmn")))]
- ""
- "or%B0 %2,%0")
-
- ;;- xor instructions
-
- (define_insn "xorsi3"
- [(set (match_operand:SI 0 "general_operand" "=rm,r")
- (xor:SI (match_operand:SI 1 "general_operand" "%0,0")
- (match_operand:SI 2 "general_operand" "ri,rm")))]
- ""
- "xor%L0 %2,%0")
-
- (define_insn "xorhi3"
- [(set (match_operand:HI 0 "general_operand" "=rm,r")
- (xor:HI (match_operand:HI 1 "general_operand" "%0,0")
- (match_operand:HI 2 "general_operand" "ri,rm")))]
- ""
- "xor%W0 %2,%0")
-
- (define_insn "xorqi3"
- [(set (match_operand:QI 0 "general_operand" "=qm")
- (xor:QI (match_operand:QI 1 "general_operand" "%0")
- (match_operand:QI 2 "general_operand" "qn")))]
- ""
- "xor%B0 %2,%0")
-
- ;;- negation instructions
- (define_insn "negsi2"
- [(set (match_operand:SI 0 "general_operand" "=rm")
- (neg:SI (match_operand:SI 1 "general_operand" "0")))]
- ""
- "neg%L0 %0")
-
- (define_insn "neghi2"
- [(set (match_operand:HI 0 "general_operand" "=rm")
- (neg:HI (match_operand:HI 1 "general_operand" "0")))]
- ""
- "neg%W0 %0")
-
- (define_insn "negqi2"
- [(set (match_operand:QI 0 "general_operand" "=qm")
- (neg:QI (match_operand:QI 1 "general_operand" "0")))]
- ""
- "neg%B0 %0")
-
- (define_insn "negsf2"
- [(set (match_operand:SF 0 "general_operand" "=f,!m")
- (neg:SF (match_operand:SF 1 "general_operand" "0,0")))]
- "TARGET_80387"
- "*FP_CALL1 (\"fchs\")")
-
- (define_insn "negdf2"
- [(set (match_operand:DF 0 "general_operand" "=f,!m")
- (neg:DF (match_operand:DF 1 "general_operand" "0,0")))]
- "TARGET_80387"
- "*FP_CALL1 (\"fchs\")")
-
- ;; Absolute value instructions
-
- (define_insn "abssf2"
- [(set (match_operand:SF 0 "general_operand" "=f,!m")
- (abs:SF (match_operand:SF 1 "general_operand" "0,0")))]
- "TARGET_80387"
- "*FP_CALL1 (\"fabs\")")
-
- (define_insn "absdf2"
- [(set (match_operand:DF 0 "general_operand" "=f,!m")
- (abs:DF (match_operand:DF 1 "general_operand" "0,0")))]
- "TARGET_80387"
- "*FP_CALL1 (\"fabs\")")
-
- ;;- one complement instructions
- (define_insn "one_cmplsi2"
- [(set (match_operand:SI 0 "general_operand" "=rm")
- (not:SI (match_operand:SI 1 "general_operand" "0")))]
- ""
- "not%L0 %0")
-
- (define_insn "one_cmplhi2"
- [(set (match_operand:HI 0 "general_operand" "=rm")
- (not:HI (match_operand:HI 1 "general_operand" "0")))]
- ""
- "not%W0 %0")
-
- (define_insn "one_cmplqi2"
- [(set (match_operand:QI 0 "general_operand" "=qm")
- (not:QI (match_operand:QI 1 "general_operand" "0")))]
- ""
- "not%B0 %0")
-
- ;;- arithmetic shift instructions
-
- (define_insn "ashlsi3"
- [(set (match_operand:SI 0 "general_operand" "=rm")
- (ashift:SI (match_operand:SI 1 "general_operand" "0")
- (match_operand:SI 2 "general_operand" "cI")))]
- ""
- "*
- {
- if (REG_P (operands[2]))
- return AS2 (sal%L0,%R0cl,%0);
- else if (REG_P (operands[1]) && GET_CODE (operands[2]) == CONST_INT
- && INTVAL (operands[2]) == 1)
- return AS2 (add%L0,%1,%1);
- return AS2 (sal%L0,%2,%1);
- }")
-
- (define_insn "ashlhi3"
- [(set (match_operand:HI 0 "general_operand" "=rm")
- (ashift:HI (match_operand:HI 1 "general_operand" "0")
- (match_operand:HI 2 "general_operand" "cI")))]
- ""
- "*
- {
- if (REG_P (operands[2]))
- return AS2 (sal%W0,%R0cl,%0);
- else
- return AS2 (sal%W0,%2,%1);
- }")
-
- (define_insn "ashlqi3"
- [(set (match_operand:QI 0 "general_operand" "=qm")
- (ashift:QI (match_operand:QI 1 "general_operand" "0")
- (match_operand:QI 2 "general_operand" "cI")))]
- ""
- "*
- {
- if (REG_P (operands[2]))
- return AS2 (sal%B0,%R0cl,%0);
- else
- return AS2 (sal%B0,%2,%1);
- }")
-
- (define_insn "ashrsi3"
- [(set (match_operand:SI 0 "general_operand" "=rm")
- (ashiftrt:SI (match_operand:SI 1 "general_operand" "0")
- (match_operand:SI 2 "general_operand" "cI")))]
- ""
- "*
- {
- if (REG_P (operands[2]))
- return AS2 (sar%L0,%R0cl,%0);
- else
- return AS2 (sar%L0,%2,%0);
- }")
-
- (define_insn "ashrhi3"
- [(set (match_operand:HI 0 "general_operand" "=rm")
- (ashiftrt:HI (match_operand:HI 1 "general_operand" "0")
- (match_operand:HI 2 "general_operand" "cI")))]
- ""
- "*
- {
- if (REG_P (operands[2]))
- return AS2 (sar%W0,%R0cl,%0);
- else
- return AS2 (sar%W0,%2,%0);
- }")
-
- (define_insn "ashrqi3"
- [(set (match_operand:QI 0 "general_operand" "=qm")
- (ashiftrt:QI (match_operand:QI 1 "general_operand" "0")
- (match_operand:QI 2 "general_operand" "cI")))]
- ""
- "*
- {
- if (REG_P (operands[2]))
- return AS2 (sar%B0,%R0cl,%0);
- return
- AS2 (sar%B0,%2,%1);
- }")
-
- ;;- logical shift instructions
-
- (define_insn "lshlsi3"
- [(set (match_operand:SI 0 "general_operand" "=rm")
- (lshift:SI (match_operand:SI 1 "general_operand" "0")
- (match_operand:SI 2 "general_operand" "cI")))]
- ""
- "*
- {
- if (REG_P (operands[2]))
- return AS2 (shl%L0,%R0cl,%0);
- else
- return AS2 (shl%L0,%2,%1);
- }")
-
- (define_insn "lshlhi3"
- [(set (match_operand:HI 0 "general_operand" "=rm")
- (lshift:HI (match_operand:HI 1 "general_operand" "0")
- (match_operand:HI 2 "general_operand" "cI")))]
- ""
- "*
- {
- if (REG_P (operands[2]))
- return AS2 (shl%W0,%R0cl,%0);
- else
- return AS2 (shl%W0,%2,%1);
- }")
-
- (define_insn "lshlqi3"
- [(set (match_operand:QI 0 "general_operand" "=qm")
- (lshift:QI (match_operand:QI 1 "general_operand" "0")
- (match_operand:QI 2 "general_operand" "cI")))]
- ""
- "*
- {
- if (REG_P (operands[2]))
- return AS2 (shl%B0,%R0cl,%0);
- else
- return AS2 (shl%B0,%2,%1);
- }")
-
- (define_insn "lshrsi3"
- [(set (match_operand:SI 0 "general_operand" "=rm")
- (lshiftrt:SI (match_operand:SI 1 "general_operand" "0")
- (match_operand:SI 2 "general_operand" "cI")))]
- ""
- "*
- {
- if (REG_P (operands[2]))
- return AS2 (shr%L0,%R0cl,%0);
- else
- return AS2 (shr%L0,%2,%1);
- }")
-
- (define_insn "lshrhi3"
- [(set (match_operand:HI 0 "general_operand" "=rm")
- (lshiftrt:HI (match_operand:HI 1 "general_operand" "0")
- (match_operand:HI 2 "general_operand" "cI")))]
- ""
- "*
- {
- if (REG_P (operands[2]))
- return AS2 (shr%W0,%%cl,%0);
- else
- return AS2 (shr%W0,%2,%1);
- }")
-
- (define_insn "lshrqi3"
- [(set (match_operand:QI 0 "general_operand" "=qm")
- (lshiftrt:QI (match_operand:QI 1 "general_operand" "0")
- (match_operand:QI 2 "general_operand" "cI")))]
- ""
- "*
- {
- if (REG_P (operands[2]))
- return AS2 (shr%B0,%%cl,%0);
- else
- return AS2 (shr%B0,%2,%1);
- }")
-
- ;;- rotate instructions
-
- (define_insn "rotlsi3"
- [(set (match_operand:SI 0 "general_operand" "=rm")
- (rotate:SI (match_operand:SI 1 "general_operand" "0")
- (match_operand:SI 2 "general_operand" "cI")))]
- ""
- "*
- {
- if (REG_P (operands[2]))
- return AS2 (rol%L0,%%cl,%0);
- else
- return AS2 (rol%L0,%2,%1);
- }")
-
- (define_insn "rotlhi3"
- [(set (match_operand:HI 0 "general_operand" "=rm")
- (rotate:HI (match_operand:HI 1 "general_operand" "0")
- (match_operand:HI 2 "general_operand" "cI")))]
- ""
- "*
- {
- if (REG_P (operands[2]))
- return AS2 (rol%W0,%%cl,%0);
- else
- return AS2 (rol%W0,%2,%1);
- }")
-
- (define_insn "rotlqi3"
- [(set (match_operand:QI 0 "general_operand" "=qm")
- (rotate:QI (match_operand:QI 1 "general_operand" "0")
- (match_operand:QI 2 "general_operand" "cI")))]
- ""
- "*
- {
- if (REG_P (operands[2]))
- return AS2 (rol%B0,%%cl,%0);
- else
- return AS2 (rol%B0,%2,%1);
- }")
-
- (define_insn "rotrsi3"
- [(set (match_operand:SI 0 "general_operand" "=rm")
- (rotatert:SI (match_operand:SI 1 "general_operand" "0")
- (match_operand:SI 2 "general_operand" "cI")))]
- ""
- "*
- {
- if (REG_P (operands[2]))
- return AS2 (ror%L0,%%cl,%0);
- else
- return AS2 (ror%L0,%2,%1);
- }")
-
- (define_insn "rotrhi3"
- [(set (match_operand:HI 0 "general_operand" "=rm")
- (rotatert:HI (match_operand:HI 1 "general_operand" "0")
- (match_operand:HI 2 "general_operand" "cI")))]
- ""
- "*
- {
- if (REG_P (operands[2]))
- return AS2 (ror%W0,%%cl,%0);
- else
- return AS2 (ror%W0,%2,%1);
- }")
-
- (define_insn "rotrqi3"
- [(set (match_operand:QI 0 "general_operand" "=qm")
- (rotatert:QI (match_operand:QI 1 "general_operand" "0")
- (match_operand:QI 2 "general_operand" "cI")))]
- ""
- "*
- {
- if (REG_P (operands[2]))
- return AS2 (ror%B0,%%cl,%0);
- else
- return AS2 (ror%B0,%2,%1);
- }")
-
- ;; Store-flag instructions.
-
- (define_insn "seq"
- [(set (match_operand:QI 0 "general_operand" "=q")
- (eq (cc0) (const_int 0)))]
- ""
- "*
- cc_status = cc_prev_status;
- return \"sete %0\";
- ")
-
- (define_insn "sne"
- [(set (match_operand:QI 0 "general_operand" "=q")
- (ne (cc0) (const_int 0)))]
- ""
- "*
- cc_status = cc_prev_status;
- return \"setne %0\";
- ")
-
- (define_insn "sgt"
- [(set (match_operand:QI 0 "general_operand" "=q")
- (gt (cc0) (const_int 0)))]
- ""
- "*
- cc_status = cc_prev_status;
- OUTPUT_JUMP (\"setg %0\", \"seta %0\", 0);
- ")
-
- (define_insn "sgtu"
- [(set (match_operand:QI 0 "general_operand" "=q")
- (gtu (cc0) (const_int 0)))]
- ""
- "* cc_status = cc_prev_status;
- return \"seta %0\"; ")
-
- (define_insn "slt"
- [(set (match_operand:QI 0 "general_operand" "=q")
- (lt (cc0) (const_int 0)))]
- ""
- "* cc_status = cc_prev_status;
- OUTPUT_JUMP (\"setl %0\", \"setb %0\", \"sets %0\"); ")
-
- (define_insn "sltu"
- [(set (match_operand:QI 0 "general_operand" "=q")
- (ltu (cc0) (const_int 0)))]
- ""
- "* cc_status = cc_prev_status;
- return \"setb %0\"; ")
-
- (define_insn "sge"
- [(set (match_operand:QI 0 "general_operand" "=q")
- (ge (cc0) (const_int 0)))]
- ""
- "* cc_status = cc_prev_status;
- OUTPUT_JUMP (\"setge %0\", \"setae %0\", \"setns %0\"); ")
-
- (define_insn "sgeu"
- [(set (match_operand:QI 0 "general_operand" "=q")
- (geu (cc0) (const_int 0)))]
- ""
- "* cc_status = cc_prev_status;
- return \"setae %0\"; ")
-
- (define_insn "sle"
- [(set (match_operand:QI 0 "general_operand" "=q")
- (le (cc0) (const_int 0)))]
- ""
- "*
- cc_status = cc_prev_status;
- OUTPUT_JUMP (\"setle %0\", \"setbe %0\", 0);
- ")
-
- (define_insn "sleu"
- [(set (match_operand:QI 0 "general_operand" "=q")
- (leu (cc0) (const_int 0)))]
- ""
- "* cc_status = cc_prev_status;
- return \"setbe %0\"; ")
-
- ;; Basic conditional jump instructions.
- ;; We ignore the overflow flag for signed branch instructions.
-
- (define_insn "beq"
- [(set (pc)
- (if_then_else (eq (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "je %l0")
-
- (define_insn "bne"
- [(set (pc)
- (if_then_else (ne (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "jne %l0")
-
- (define_insn "bgt"
- [(set (pc)
- (if_then_else (gt (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "*OUTPUT_JUMP (\"jg %l0\", \"ja %l0\", 0)")
-
- (define_insn "bgtu"
- [(set (pc)
- (if_then_else (gtu (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "ja %l0")
-
- (define_insn "blt"
- [(set (pc)
- (if_then_else (lt (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "*OUTPUT_JUMP (\"jl %l0\", \"jb %l0\", \"js %l0\")")
-
- (define_insn "bltu"
- [(set (pc)
- (if_then_else (ltu (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "jb %l0")
-
- (define_insn "bge"
- [(set (pc)
- (if_then_else (ge (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "*OUTPUT_JUMP (\"jge %l0\", \"jae %l0\", \"jns %l0\")")
-
- (define_insn "bgeu"
- [(set (pc)
- (if_then_else (geu (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "jae %l0")
-
- (define_insn "ble"
- [(set (pc)
- (if_then_else (le (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "*OUTPUT_JUMP (\"jle %l0\", \"jbe %l0\", 0) ")
-
- (define_insn "bleu"
- [(set (pc)
- (if_then_else (leu (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "jbe %l0")
-
- ;; Negated conditional jump instructions.
-
- (define_insn ""
- [(set (pc)
- (if_then_else (eq (cc0)
- (const_int 0))
- (pc)
- (label_ref (match_operand 0 "" ""))))]
- ""
- "jne %l0")
-
- (define_insn ""
- [(set (pc)
- (if_then_else (ne (cc0)
- (const_int 0))
- (pc)
- (label_ref (match_operand 0 "" ""))))]
- ""
- "je %l0")
-
- (define_insn ""
- [(set (pc)
- (if_then_else (gt (cc0)
- (const_int 0))
- (pc)
- (label_ref (match_operand 0 "" ""))))]
- ""
- "*OUTPUT_JUMP (\"jle %l0\", \"jbe %l0\", 0) ")
-
- (define_insn ""
- [(set (pc)
- (if_then_else (gtu (cc0)
- (const_int 0))
- (pc)
- (label_ref (match_operand 0 "" ""))))]
- ""
- "jbe %l0")
-
- (define_insn ""
- [(set (pc)
- (if_then_else (lt (cc0)
- (const_int 0))
- (pc)
- (label_ref (match_operand 0 "" ""))))]
- ""
- "*OUTPUT_JUMP (\"jge %l0\", \"jae %l0\", \"jns %l0\")
- ")
-
- (define_insn ""
- [(set (pc)
- (if_then_else (ltu (cc0)
- (const_int 0))
- (pc)
- (label_ref (match_operand 0 "" ""))))]
- ""
- "jae %l0")
-
- (define_insn ""
- [(set (pc)
- (if_then_else (ge (cc0)
- (const_int 0))
- (pc)
- (label_ref (match_operand 0 "" ""))))]
- ""
- "*OUTPUT_JUMP (\"jl %l0\", \"jb %l0\", \"js %l0\")")
-
- (define_insn ""
- [(set (pc)
- (if_then_else (geu (cc0)
- (const_int 0))
- (pc)
- (label_ref (match_operand 0 "" ""))))]
- ""
- "jb %l0")
-
- (define_insn ""
- [(set (pc)
- (if_then_else (le (cc0)
- (const_int 0))
- (pc)
- (label_ref (match_operand 0 "" ""))))]
- ""
- "*OUTPUT_JUMP (\"jg %l0\", \"ja %l0\", 0)")
-
- (define_insn ""
- [(set (pc)
- (if_then_else (leu (cc0)
- (const_int 0))
- (pc)
- (label_ref (match_operand 0 "" ""))))]
- ""
- "ja %l0")
-
- ;; Unconditional and other jump instructions
- (define_insn "jump"
- [(set (pc)
- (label_ref (match_operand 0 "" "")))]
- ""
- "jmp %l0")
-
- (define_insn "tablejump"
- [(set (pc) (match_operand:SI 0 "general_operand" "rm"))
- (use (label_ref (match_operand 1 "" "")))]
- ""
- "*
- {
- CC_STATUS_INIT;
-
- return \"jmp %*%0\";
- }")
-
- /*
- (define_insn ""
- [(set (pc)
- (if_then_else
- (ne (compare (minus:HI (match_operand:HI 0 "general_operand" "c")
- (const_int 1))
- (const_int -1))
- (const_int 0))
- (label_ref (match_operand 1 "" "g"))
- (pc)))
- (set (match_dup 0)
- (minus:HI (match_dup 0)
- (const_int 1)))]
- ""
- "loop %l1")
-
- (define_insn ""
- [(set (pc)
- (if_then_else
- (ne (compare (const_int -1)
- (minus:SI (match_operand:SI 0 "general_operand" "c")
- (const_int 1)))
- (const_int 0))
- (label_ref (match_operand 1 "" "g"))
- (pc)))
- (set (match_dup 0)
- (minus:SI (match_dup 0)
- (const_int 1)))]
- ""
- "loop %l1")
- */
-
- ;; Call subroutine returning no value.
- (define_insn "call"
- [(call (match_operand:QI 0 "indirect_operand" "m")
- (match_operand:SI 1 "general_operand" "g"))]
- ;; Operand 1 not really used on the m68000.
- ""
- "*
- {
- if (GET_CODE (operands[0]) == MEM
- && ! CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
- {
- operands[0] = XEXP (operands[0], 0);
- return \"call %*%0\";
- }
- else
- return \"call %0\";
- }")
-
- ;; Call subroutine, returning value in operand 0
- ;; (which must be a hard register).
- (define_insn "call_value"
- [(set (match_operand 0 "" "=rf")
- (call (match_operand:QI 1 "indirect_operand" "m")
- (match_operand:SI 2 "general_operand" "g")))]
- ;; Operand 2 not really used on the m68000.
- ""
- "*
- {
- if (GET_CODE (operands[1]) == MEM
- && ! CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
- {
- operands[1] = XEXP (operands[1], 0);
- output_asm_insn (\"call %*%1\", operands);
- }
- else
- output_asm_insn (\"call %1\", operands);
-
- if (GET_MODE (operands[0]) == DFmode
- || GET_MODE (operands[0]) == SFmode)
- {
- /* fp_pop_level++; */
- /* pop if reg dead */
- if (!FP_REG_P (operands[0]))
- abort ();
- if (top_dead_p (insn))
- {
- POP_ONE_FP;
- }
- }
- RET;
- }")
-
- (define_insn "nop"
- [(const_int 0)]
- ""
- "nop")
-
- ;;- Local variables:
- ;;- mode:emacs-lisp
- ;;- comment-start: ";;- "
- ;;- eval: (set-syntax-table (copy-sequence (syntax-table)))
- ;;- eval: (modify-syntax-entry ?[ "(]")
- ;;- eval: (modify-syntax-entry ?] ")[")
- ;;- eval: (modify-syntax-entry ?{ "(}")
- ;;- eval: (modify-syntax-entry ?} "){")
- ;;- End:
-